import {
  call, put, all, takeLatest, select
} from 'redux-saga/effects'
import api from '@API'
import {
  GET_RECOMMEND_DOCTORS,
  GET_DOCTOR_DETAIL,
  GET_DOCTOR_BY_TAG_IDS,
  GET_RECOMMEND_DOCTORS_HOME,
  GET_DOCTORS,
  GET_DOCTOR_BY_TAG_ID
} from '@ACTIONS/doctor'
import { DEFAULT_TAKE } from '@CONSTANTS/common'
import {
  getRecommendDoctorList, getDoctorListByTagIds, getServicePackDoctors, getDoctorListByTagId
} from './dataSelect'

const getRecommendDoctors = function* getRecommendDoctors(action) {
  try {
    const { payload } = action
    const { skip } = payload || {}
    const list = yield select(getRecommendDoctorList)
    const realSkip = skip === 0 ? 0 : list.length
    const data = yield call(api.getRecommendDoctors, {
      ...payload,
      skip: realSkip,
    })
    yield put({ type: GET_RECOMMEND_DOCTORS.SUCCESS, data, skip: realSkip })
  } catch (error) {
    yield put({ type: GET_RECOMMEND_DOCTORS.FAILURE, error })
  }
}

const getRecommendDoctorsHome = function* getRecommendDoctorsHome(action) {
  try {
    const { payload = {} } = action
    const data = yield call(api.getRecommendDoctorsHome, payload)
    yield put({ type: GET_RECOMMEND_DOCTORS_HOME.SUCCESS, data })
  } catch (error) {
    yield put({ type: GET_RECOMMEND_DOCTORS_HOME.FAILURE, error })
  }
}

const getDoctorDetail = function* getDoctorDetail(action) {
  try {
    const { payload, callback } = action
    const doctorDetail = yield call(api.getDoctorDetail, payload)
    yield put({ type: GET_DOCTOR_DETAIL.SUCCESS, doctorDetail })
    callback?.(doctorDetail)
  } catch (error) {
    yield put({ type: GET_DOCTOR_DETAIL.FAILURE, error })
  }
}

const getDoctorsByTagIds = function* getDoctorsByTagIds(action) {
  try {
    const { payload: { tIds, skip, isRecommend } } = action
    const preDoctorList = yield select(getDoctorListByTagIds)
    const realSkip = skip === 0 ? 0 : preDoctorList?.length

    const fetchApi = isRecommend ? api.getRecommendDoctors : api.getDoctorsByTagIds
    const payload = { skip: realSkip, take: DEFAULT_TAKE, ...(isRecommend ? {} : { tIds }) }
    const { Doctors: doctorListByTagIds } = yield call(fetchApi, payload)

    yield put({ type: GET_DOCTOR_BY_TAG_IDS.SUCCESS, doctorListByTagIds, canLoadMore: doctorListByTagIds.length >= DEFAULT_TAKE })
  } catch (error) {
    yield put({ type: GET_DOCTOR_BY_TAG_IDS.FAILURE, error })
  }
}
const getDoctorsByTagId = function* getDoctorsByTagId(action) {
  try {
    const { payload: { tId, skip } } = action
    const preDoctorList = yield select(getDoctorListByTagId)
    const realSkip = skip === 0 ? 0 : preDoctorList?.length
    const { Doctors: doctorListByTagIds } = yield call(api.getRecommendDoctorsTopic, { tId, skip: realSkip, take: DEFAULT_TAKE })
    yield put({ type: GET_DOCTOR_BY_TAG_ID.SUCCESS, doctorListByTagIds, canLoadMore: doctorListByTagIds.length >= DEFAULT_TAKE })
  } catch (error) {
    yield put({ type: GET_DOCTOR_BY_TAG_ID.FAILURE, error })
  }
}

const getDoctors = function* getDoctors(action) {
  try {
    const { payload: { skip, ...rest } = {} } = action
    const preList = yield select(getServicePackDoctors)
    const realSkip = skip === 0 ? 0 : preList.length
    const { Doctors } = yield call(api.getRecommendDoctors, {
      sp: true, skip: realSkip, take: DEFAULT_TAKE, ...rest
    })
    yield put({
      type: GET_DOCTORS.SUCCESS,
      data: Doctors,
      canLoadMore: Doctors?.length >= DEFAULT_TAKE,
      skip
    })
  } catch (error) {
    yield put({ type: GET_DOCTORS.FAILURE, error })
  }
}

export default function* rootSaga() {
  yield all([
    takeLatest(GET_RECOMMEND_DOCTORS.REQUEST, getRecommendDoctors),
    takeLatest(GET_DOCTOR_DETAIL.REQUEST, getDoctorDetail),
    takeLatest(GET_DOCTOR_BY_TAG_IDS.REQUEST, getDoctorsByTagIds),
    takeLatest(GET_DOCTOR_BY_TAG_ID.REQUEST, getDoctorsByTagId),
    takeLatest(GET_RECOMMEND_DOCTORS_HOME.REQUEST, getRecommendDoctorsHome),
    takeLatest(GET_DOCTORS.REQUEST, getDoctors),
  ])
}
